<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
  <title>Description of v_randiscr</title>
  <meta name="keywords" content="v_randiscr">
  <meta name="description" content="V_RANDISCR Generate discrete random numbers with specified probabiities [X]=(P,N,A)">
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta name="generator" content="m2html &copy; 2003 Guillaume Flandin">
  <meta name="robots" content="index, follow">
  <link type="text/css" rel="stylesheet" href="../m2html.css">
</head>
<body>
<a name="_top"></a>
<div><a href="../index.html">Home</a> &gt;  <a href="index.html">v_mfiles</a> &gt; v_randiscr.m</div>

<!--<table width="100%"><tr><td align="left"><a href="../index.html"><img alt="<" border="0" src="../left.png">&nbsp;Master index</a></td>
<td align="right"><a href="index.html">Index for v_mfiles&nbsp;<img alt=">" border="0" src="../right.png"></a></td></tr></table>-->

<h1>v_randiscr
</h1>

<h2><a name="_name"></a>PURPOSE <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
<div class="box"><strong>V_RANDISCR Generate discrete random numbers with specified probabiities [X]=(P,N,A)</strong></div>

<h2><a name="_synopsis"></a>SYNOPSIS <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
<div class="box"><strong>function x=v_randiscr(p,n,a) </strong></div>

<h2><a name="_description"></a>DESCRIPTION <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
<div class="fragment"><pre class="comment">V_RANDISCR Generate discrete random numbers with specified probabiities [X]=(P,N,A)

 Usage: (1) v_randiscr([],10)        % generate 10 uniform random binary values
        (2) v_randiscr(2:6,10)       % generate 10 random numbers in the range 1:5
                                       with probabilities [2 3 4 5 6]/20
        (3) v_randiscr([],10,'abcd') % generate a string of 10 random
                                       characters equiprobable from 'abcd'
        (4) v_randiscr([],-3,'abcd') % generate a string of 3 distinct random
                                       characters equiprobable from 'abcd'

 Inputs: P  vector or n-D array of probabilities (not necessarily normalized) [default = uniform]
         N  number of random values to generate: +ve=with and -ve=without replacement [default = 1]
         A  output alphabet [default = 1:length(p) or 0:1 if p is empty]

 Outputs: X  vector of not necessarily distinct values taken from alphabet A
             If A is omitted and P is a matrix, each row of X(N,M) will contain the M coordinates
             of a random element of P.

 The vector P is internally normalized by dividing by its sum.</pre></div>

<!-- crossreference -->
<h2><a name="_cross"></a>CROSS-REFERENCE INFORMATION <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
This function calls:
<ul style="list-style-image:url(../matlabicon.gif)">
</ul>
This function is called by:
<ul style="list-style-image:url(../matlabicon.gif)">
<li><a href="v_randvec.html" class="code" title="function x=v_randvec(n,m,c,w,mode)">v_randvec</a>	V_RANDVEC  Generate real or complex GMM/lognormal random vectors X=(N,M,C,W,MODE)</li></ul>
<!-- crossreference -->


<h2><a name="_source"></a>SOURCE CODE <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
<div class="fragment"><pre>0001 <a name="_sub0" href="#_subfunctions" class="code">function x=v_randiscr(p,n,a)</a>
0002 <span class="comment">%V_RANDISCR Generate discrete random numbers with specified probabiities [X]=(P,N,A)</span>
0003 <span class="comment">%</span>
0004 <span class="comment">% Usage: (1) v_randiscr([],10)        % generate 10 uniform random binary values</span>
0005 <span class="comment">%        (2) v_randiscr(2:6,10)       % generate 10 random numbers in the range 1:5</span>
0006 <span class="comment">%                                       with probabilities [2 3 4 5 6]/20</span>
0007 <span class="comment">%        (3) v_randiscr([],10,'abcd') % generate a string of 10 random</span>
0008 <span class="comment">%                                       characters equiprobable from 'abcd'</span>
0009 <span class="comment">%        (4) v_randiscr([],-3,'abcd') % generate a string of 3 distinct random</span>
0010 <span class="comment">%                                       characters equiprobable from 'abcd'</span>
0011 <span class="comment">%</span>
0012 <span class="comment">% Inputs: P  vector or n-D array of probabilities (not necessarily normalized) [default = uniform]</span>
0013 <span class="comment">%         N  number of random values to generate: +ve=with and -ve=without replacement [default = 1]</span>
0014 <span class="comment">%         A  output alphabet [default = 1:length(p) or 0:1 if p is empty]</span>
0015 <span class="comment">%</span>
0016 <span class="comment">% Outputs: X  vector of not necessarily distinct values taken from alphabet A</span>
0017 <span class="comment">%             If A is omitted and P is a matrix, each row of X(N,M) will contain the M coordinates</span>
0018 <span class="comment">%             of a random element of P.</span>
0019 <span class="comment">%</span>
0020 <span class="comment">% The vector P is internally normalized by dividing by its sum.</span>
0021 
0022 <span class="comment">% Somewhat similar in function to RANDSRC in the comms toolbox</span>
0023 
0024 <span class="comment">% Revisions:</span>
0025 <span class="comment">%   2020-08-01 Fixed error when n=-(alphabet size)</span>
0026 <span class="comment">%   2020-11-03 Clarified comments and speeded up non-replacement sampling</span>
0027 <span class="comment">%              with uniform probabilities</span>
0028 <span class="comment">%</span>
0029 <span class="comment">%   Copyright (c) 2005-2012 Mike Brookes,  mike.brookes@ic.ac.uk</span>
0030 <span class="comment">%      Version: $Id: v_randiscr.m 10865 2018-09-21 17:22:45Z dmb $</span>
0031 <span class="comment">%</span>
0032 <span class="comment">%   VOICEBOX is a MATLAB toolbox for speech processing.</span>
0033 <span class="comment">%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html</span>
0034 <span class="comment">%</span>
0035 <span class="comment">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span>
0036 <span class="comment">%   This program is free software; you can redistribute it and/or modify</span>
0037 <span class="comment">%   it under the terms of the GNU General Public License as published by</span>
0038 <span class="comment">%   the Free Software Foundation; either version 2 of the License, or</span>
0039 <span class="comment">%   (at your option) any later version.</span>
0040 <span class="comment">%</span>
0041 <span class="comment">%   This program is distributed in the hope that it will be useful,</span>
0042 <span class="comment">%   but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
0043 <span class="comment">%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
0044 <span class="comment">%   GNU General Public License for more details.</span>
0045 <span class="comment">%</span>
0046 <span class="comment">%   You can obtain a copy of the GNU General Public License from</span>
0047 <span class="comment">%   http://www.gnu.org/copyleft/gpl.html or by writing to</span>
0048 <span class="comment">%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.</span>
0049 <span class="comment">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span>
0050 gota=nargin&gt;2;
0051 <span class="keyword">if</span> nargin&lt;1 || ~numel(p)
0052     <span class="keyword">if</span> gota
0053         p=ones(1,length(a));
0054     <span class="keyword">else</span>
0055         p=ones(1,2);
0056         a=(0:1)';
0057         gota=1;
0058     <span class="keyword">end</span>
0059 <span class="keyword">end</span>
0060 <span class="keyword">if</span> nargin&lt;2 || ~numel(n)
0061     n=1;
0062 <span class="keyword">end</span>
0063 q=p(:);
0064 d=length(q);                    <span class="comment">% size of output alphabet</span>
0065 <span class="keyword">if</span> gota &amp;&amp; d~=numel(a)
0066     error(<span class="string">'sizes of alphabet and probability vector/matrix must match'</span>);
0067 <span class="keyword">end</span>
0068 <span class="keyword">if</span> n&gt;1                          <span class="comment">% sample with replacement</span>
0069     dn=d+n-1;
0070     z=zeros(dn,1);                <span class="comment">% array to hold random numbers</span>
0071     z(1:d)=cumsum(q/sum(q));       <span class="comment">% last value is overwritten in the next line</span>
0072     z(d:end)=rand(n,1);         <span class="comment">% create a random number for each sample</span>
0073     [y,iy]=sort(z);             <span class="comment">% the original entries z(1:d-1) now divide the samples into bins for each possible value</span>
0074     y(iy)=(1:dn)';                 <span class="comment">% create inverse index</span>
0075     m=zeros(dn,1);
0076     m(y(1:d-1))=1;                 <span class="comment">% set original initial d-1 values to 1</span>
0077     m(1)=m(1)+1;                <span class="comment">% and also the first value</span>
0078     m=cumsum(m);                <span class="comment">% label each of the random nuumbers with its corresponding value in 1:d</span>
0079     x=m(y(d:dn));               <span class="comment">% find the partitions of the n random numbers</span>
0080 <span class="keyword">else</span>                            <span class="comment">% sample without replacement</span>
0081     n=abs(n);                   <span class="comment">% number of samples needed</span>
0082     <span class="keyword">if</span> n&gt;d
0083         error(<span class="string">'Number of output samples exceeds alphabet size'</span>);
0084     <span class="keyword">end</span>
0085     <span class="keyword">if</span> all(q==q(1))             <span class="comment">% if all probabilities are equal</span>
0086         [y,iy]=sort(rand(d,1)); <span class="comment">% iy is a random permutation of 1:d</span>
0087         x=iy(1:n);              <span class="comment">% select the first n values</span>
0088     <span class="keyword">else</span>
0089         f=(1:d)';               <span class="comment">% initialize the alphabet to 1:d</span>
0090         x=zeros(n,1);           <span class="comment">% space for the output samples</span>
0091         nn=n;                   <span class="comment">% number of samples remaining</span>
0092         <span class="keyword">while</span> nn&gt;0              <span class="comment">% number of samples remaining</span>
0093             dd=numel(f);        <span class="comment">% alphabet size (always &gt;=nn)</span>
0094             <span class="keyword">if</span> dd==1            <span class="comment">% singleton alphabet</span>
0095                 x(n)=f;         <span class="comment">% set remaining sample to the only remaining value</span>
0096                 nn=0;           <span class="comment">% and set remaining value count to zero</span>
0097             <span class="keyword">else</span>
0098                 qq=q(f);                        <span class="comment">% remaiing alphabet probabilities</span>
0099                 dn=dd+nn-1;
0100                 z=zeros(dn,1);                  <span class="comment">% array to hold random numbers</span>
0101                 z(1:dd)=cumsum(qq/sum(qq));     <span class="comment">% last value is overwritten in the next line</span>
0102                 z(dd:dn)=rand(nn,1);            <span class="comment">% create a random number for each sample</span>
0103                 [y,iy]=sort(z);                 <span class="comment">% the original entries z(1:dd-1) now divide the samples into bins for each possible value</span>
0104                 y(iy)=(1:dn)';                  <span class="comment">% create inverse index</span>
0105                 m=zeros(dn,1);
0106                 m(y(1:dd-1))=1;                   <span class="comment">% set original initial dd-1 values to 1</span>
0107                 m(1)=m(1)+1;                    <span class="comment">% and also the first value</span>
0108                 m=cumsum(m);                    <span class="comment">% label each of the random nuumbers with its corresponding value in 1:dd</span>
0109                 z=m(y(dd:dn));                  <span class="comment">% find the partitions of the nn random numbers</span>
0110                 [y,iy]=sort(z);                 <span class="comment">% sorts the positions within each partition</span>
0111                 z(iy(1+find(y(1:nn-1)==y(2:nn))))=[];          <span class="comment">% keep only the first sample from each partition</span>
0112                 k=numel(z);                     <span class="comment">% number of new samples</span>
0113                 x(n-nn+1:n-nn+k)=f(z);          <span class="comment">% add new samples into output array</span>
0114                 nn=nn-k;                        <span class="comment">% number of remaining samples</span>
0115                 f(z)=[];                        <span class="comment">% remove used entries from alphabet</span>
0116             <span class="keyword">end</span>
0117         <span class="keyword">end</span>
0118     <span class="keyword">end</span>
0119 <span class="keyword">end</span>
0120 <span class="keyword">if</span> gota
0121     x=a(x);                                     <span class="comment">% select from output alphabet</span>
0122 <span class="keyword">elseif</span> length(q)&gt;length(p)                      <span class="comment">% need multiple dimensions</span>
0123     v=x-1;
0124     s=cumprod(size(p));
0125     m=length(s);
0126     s(2:end)=s(1:end-1);
0127     s(1)=1;
0128     x=zeros(n,m);
0129     <span class="keyword">for</span> i=m:-1:1
0130         x(:,i)=1+floor(v/s(i));                 <span class="comment">% find indices starting with the last</span>
0131         v=rem(v,s(i));
0132     <span class="keyword">end</span>
0133 <span class="keyword">end</span></pre></div>
<hr><address>Generated by <strong><a href="http://www.artefact.tk/software/matlab/m2html/">m2html</a></strong> &copy; 2003</address>
</body>
</html>